//
// CPodcastPlugin.cpp
// Your copyright notice
//
#include "PodcastPlugin.h"
#include "PodcastUI.h"

#include "PodcastPlugin.rsg"
#include "PodcastPlayer.h"
#include "RssFeed.h"
#include "PluginUtility.h"

#include <aknquerydialog.h>		//CAknTextQueryDialog

// Identifying string for plugin
_LIT(KPodcastPlugin, "Podcast");

enum TPlayerPluginCommandId
{
	EPluginCommandId = 0x6100,
	EEnterRssCommandId
};

// Construction and destruction functions
CPodcastPlugin* CPodcastPlugin::NewL(TAny* aInitParams)
{
	//Create plugin
	CPodcastPlugin* self = new(ELeave) CPodcastPlugin(aInitParams);
	CleanupStack::PushL(self);
	self->ConstructL(); 
	CleanupStack::Pop();
	return self;
}

CPodcastPlugin::~CPodcastPlugin()
{
	//Clean objects
	DELETE(iPodcastPlayer);
	DELETE(iRssReader);
	DELETE(iPodcastUI);

	//Delete resource file
	CCoeEnv::Static()->DeleteResourceFile(iOffset);
}

CPodcastPlugin::CPodcastPlugin(TAny* aInitParams)
:	iInitParams((CPluginInterface::TPluginInterfaceInitParams*)aInitParams), 
iPodcastPlayer(NULL), iRssReader(NULL), iPodcastUI(NULL), iOnImageReadyCallback(&OnImageIsReady, this),
iState(EStateNotReady)
{
}

void CPodcastPlugin::ConstructL()
{
	//Create podcast player
	iPodcastPlayer = CPodcastPlayer::NewL(*this);

	//Create UI manager
	iPodcastUI = CPodcastUI::NewL();

	//Add resource file to plugin
	AddResourceFileL();
}

void CPodcastPlugin::AddResourceFileL()
{
	TFileName f;

	//Get rsc filename
#if __WINS__
	f.Append(_L("Z:\\system\\libs\\plugins\\PodcastPlugin.rsc"));

#else
	Dll::FileName(f);

	//Change dll by rsc
	f.Replace(f.Find(_L(".dll")), 4, _L(".rsc"));
#endif

	//Read resource compiled file 
	iOffset = CEikonEnv::Static()->AddResourceFileL(f);
}

const TDesC& CPodcastPlugin::GetMenuText()
{
	return KPodcastPlugin;
}

TInt CPodcastPlugin::GetMenuCommand()
{
	return EPluginCommandId;
}

void CPodcastPlugin::AddExtraMenu(CEikMenuPane* aMenuPane)
{
	//Select rss feed address..
	CPluginUtility::AddMenuItem(EEnterRssCommandId, _L("Subscribe"), aMenuPane);
}

void CPodcastPlugin::HandleCommandL(TInt aCommand)
{
	switch (aCommand)
	{
	case EEnterRssCommandId:
		SelectRssFeedL();
		break;
	}
}

TKeyResponse CPodcastPlugin::HandleKeyEventL(const TKeyEvent& aKeyEvent, TEventCode /*aType*/)
{
    switch (aKeyEvent.iCode)
	{
		case EKeyUpArrow:
		{
			iPodcastUI->SelectPreviousItem();
			return EKeyWasConsumed;
		}
		case EKeyDownArrow:
		{
			iPodcastUI->SelectNextItem();
			return EKeyWasConsumed;
		}
		case EKeyDevice3:
		{
			//Play
			PlayL();
		}
	}
	return EKeyWasNotConsumed;
}

void CPodcastPlugin::Draw(CWindowGc& aGc, const TRect& aRect) const
{
	//Draw ui
	iPodcastUI->Draw(aGc, aRect);
}

void CPodcastPlugin::SetContainer(MPluginContainer* aContainer)
{
	CPluginInterface::SetContainer(aContainer);
	iPodcastUI->SetContainer(aContainer);
}

void CPodcastPlugin::Activate()
{
	//Activate ui
	iPodcastUI->Activate();
}

void CPodcastPlugin::Deactivate()
{
	//Stop playing
	if (IsReadyToStop()) StopL();

	//Deactivate ui
	iPodcastUI->Deactivate();
}

TRgb CPodcastPlugin::BackBorderColor() const { return iPodcastUI->BackBorderColor(); }
TRgb CPodcastPlugin::BackShadowColor() const { return iPodcastUI->BackShadowColor(); }
TRgb CPodcastPlugin::BackColor() const { return iPodcastUI->BackColor(); }
TRgb CPodcastPlugin::InsideBorderColor() const { return iPodcastUI->InsideBorderColor(); }
TRgb CPodcastPlugin::InsideColor() const { return iPodcastUI->InsideColor(); }
TRgb CPodcastPlugin::ForeColor() const { return iPodcastUI->ForeColor(); }

void CPodcastPlugin::PlayL()
{
	if (!IsReadyToPlay()) return;

	//Stop & Play
	if (IsReadyToStop()) StopL();

	//Check if is playable
	if (!iPodcastUI->GetSelectedItem()->IsPlayable())
	{
		iPodcastUI->SetTickerText(_L("Current feed is not playable."));
		iPodcastUI->SetTickerIcon(CPodcastUI::EError);
		return;
	}

	//Set text and icon
	BufferStateChanged(ETrue, 0);
	iPodcastUI->SetIsPlaying(ETrue);

	//Do streaming over url of selected item
	iPodcastPlayer->StartL(iPodcastUI->GetSelectedItem()->Enclosure().Url());

	//Set state playing
	iState = EStatePlaying;
}

void CPodcastPlugin::StopL()
{
	//Set icon
	iPodcastUI->SetTickerIcon(CPodcastUI::EStop);
	iPodcastUI->SetTickerText(_L("Stopped"));

	//Stop player
	iPodcastPlayer->StopL();
	iPodcastUI->SetIsPlaying(EFalse);
	
	iState = EStateReadyToPlay;
}

TBool CPodcastPlugin::IsReadyToPlay() 
{ 
	return (iState == EStateReadyToPlay);
}

TBool CPodcastPlugin::IsReadyToStop()
{
	return (iState == EStatePlaying);
}

TInt CPodcastPlugin::Volume()
{
	return iPodcastPlayer->Volume();
}

void CPodcastPlugin::SetVolume(TInt aVolume)
{
	iPodcastPlayer->SetVolume(aVolume);
}

void CPodcastPlugin::SelectRssFeedL()
{
	const TInt KMaxRssFeedLength = 255;
	TBuf<KMaxRssFeedLength> rssFeed;
	rssFeed.Append(_L("http://4-cast.tv/rss.xml"));

	//Show dialog
	CAknTextQueryDialog* rssFeedQuery = CAknTextQueryDialog::NewL(rssFeed);
	CleanupStack::PushL(rssFeedQuery);
	rssFeedQuery->SetPromptL(_L("Enter RSS feed:"));
	CleanupStack::Pop(rssFeedQuery);

	if (rssFeedQuery->ExecuteLD(R_DATAQUERY_DATA_QUERY))
	{
		//Stop before open new url
		if (IsReadyToStop()) StopL();

		//Download rss feed
		DownloadAndParseRssFeed(rssFeed);
	}
}

void CPodcastPlugin::DownloadAndParseRssFeed(const TDesC& aUri)
{
	//Set text and icon
	iPodcastUI->SetTickerText(_L("Loading rss feed ..."));
	iPodcastUI->SetTickerIcon(CPodcastUI::EBuffering);

	//Create reader
	DELETE(iRssReader);
	iRssReader = CRssReader::NewL(aUri, *this);

	//Start reading
	iRssReader->StartL();
}

void CPodcastPlugin::DocumentEnd()
{
	//Rss feed loaded ok.
	LoadRssFeed(iRssReader->GetRssFeed());

	//Let's load background image (asynchronous!)
	if (iRssFeed->ImageUrl().Length() > 0)
	{
		iPodcastUI->SetTickerText(_L("Loading image ..."));
		iPodcastUI->SetImageUrl(iRssFeed->ImageUrl(), iOnImageReadyCallback);
	}
	else
	{
		ChangeState();
	}
}

void CPodcastPlugin::RunError(const TDesC& aErrorDesc, TInt aError)
{
	//An error has occurred. Set icon and text
	iPodcastUI->SetTickerIcon(CPodcastUI::EError);

	TBuf<256> text;
	text.AppendFormat(_L("Error %d: "), aError);
	text.Append(aErrorDesc);
	iPodcastUI->SetTickerText(text);

	iState = EStateNotReady;
}

void CPodcastPlugin::LoadRssFeed(TRssFeed* aRssFeed)
{
	iRssFeed = aRssFeed;
	iPodcastUI->SetRssFeed(iRssFeed);
}

void CPodcastPlugin::BufferStateChanged(TBool aIsBuffering, TInt aPercent)
{
	iPodcastUI->SetIsBuffering(aIsBuffering, aPercent);
}

void CPodcastPlugin::Finished()
{
	StopL();
	iPodcastUI->SetTickerText(_L("Feed has finished."));
}

void CPodcastPlugin::ChangeState()
{
	iPodcastUI->SetTickerText(_L(""));
	iPodcastUI->SetTickerIcon(CPodcastUI::ENone);

	//Change state depending on feeds
	iState = (iRssFeed->GetItems().Count() > 0) ? EStateReadyToPlay : EStateNotReady;
}

TInt CPodcastPlugin::OnImageIsReady(TAny* aAny)
{
	CPodcastPlugin* self = (CPodcastPlugin*)aAny;
	self->ChangeState();
}